package com.rules.drools.service;

import com.alicp.jetcache.anno.CacheType;
import com.alicp.jetcache.anno.Cached;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rules.core.exception.CustomException;
import com.rules.core.utils.CollectionUtil;
import com.rules.core.utils.PageUtils;
import com.rules.core.utils.Query;
import com.rules.core.utils.Result;
import com.rules.drools.dao.InfoDao;
import com.rules.drools.entity.*;
import com.rules.drools.vo.PropertyRelVo;
import com.rules.drools.vo.req.RulesInfoEntityReqVo;
import com.rules.drools.vo.resp.InfoListVo;
import org.dozer.Mapper;
import org.dozer.MappingException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service("infoService")
public class InfoService extends ServiceImpl<InfoDao, InfoEntity> {
    @Autowired
    private Mapper dozerMapper;
    @Autowired
    private ConditionInfoService conditionInfoService;
    @Autowired
    private PropertyRelService propertyRelService;
    @Autowired
    private PropertyInfoService propertyInfoService;
    @Autowired
    private ActionRuleRelService actionRuleRelService;
    @Autowired
    private ActionParamValueInfoService actionParamValueInfoService;

    public PageUtils queryPage(Map<String, Object> params) {
        IPage<InfoListVo> page = this.baseMapper.pageInfoList(new Query<InfoListVo>().getPage(params), params);
        return new PageUtils(page);
    }


    /**
     * <p>
     * 方法说明: 根据规则获取已经配置的属性信息
     *
     * @param ruleId 参数
     */
    @Cached(name = "propertyRelVo_findRulePropertyListByRuleId", cacheType = CacheType.LOCAL, key = "#ruleId", expire = 60)
    public List<PropertyRelVo> findRulePropertyListByRuleId(final Long ruleId) {
        return this.baseMapper.findRulePropertyListByRuleId(ruleId);
    }

    /**
     * <p>
     * 方法说明: 根据场景获取对应的规则规则信息
     *
     * @param baseRuleSceneInfo 参数
     */
    @Cached(name = "infoEntity_findBaseRuleListByScene", cacheType = CacheType.LOCAL, key = "#baseRuleSceneInfo.sceneIdentify", expire = 60)
    public List<InfoEntity> findBaseRuleListByScene(SceneInfoEntity baseRuleSceneInfo) {
        return this.baseMapper.findBaseRuleListByScene(baseRuleSceneInfo);
    }

    /**
     * @return
     * @Author gz
     * @Description 保存
     * @Date 2019/7/12 17:51
     * @Param reqVo
     */
    @Transactional(rollbackFor = Exception.class)
    public Result save(RulesInfoEntityReqVo reqVo) {
        try {
            boolean isUpdate = reqVo.getRuleId()!=null;
            InfoEntity map = dozerMapper.map(reqVo, InfoEntity.class);
            this.saveOrUpdate(map);
            // 规则条件
            List<ConditionInfoEntity> conditionInfoItem = reqVo.getConditionInfoItem();
            if (CollectionUtil.collectionIsNull(conditionInfoItem)) {
                return Result.error("条件不能为空");
            }
            if(isUpdate){
                // 通过规则id删除
                Long ruleId = map.getRuleId();
                // 条件
                conditionInfoService.removeByRuleId(ruleId);
                // 规则属性
                propertyRelService.removeByRuleId(ruleId);
                // 规则动作
                actionRuleRelService.removeByRuleId(ruleId);

            }
            List<ConditionInfoEntity> collect = conditionInfoItem.stream().map(con -> {
                // 设置规则id
                con.setRuleId(map.getRuleId());
                return con;
            }).collect(Collectors.toList());
            conditionInfoService.saveBatch(collect);
            // 规则属性
            List<PropertyRelVo> propertyInfoItem = reqVo.getPropertyInfoItem();
            if (!CollectionUtil.collectionIsNull(propertyInfoItem)) {
                // 保存规则属性
                propertyInfoItem.stream().forEach(property -> {
           /*       PropertyInfoEntity proEntity = dozerMapper.map(property, PropertyInfoEntity.class);
                 boolean save = propertyInfoService.save(proEntity);*/
                    PropertyRelEntity relEntity = new PropertyRelEntity();
                    relEntity.setRuleId(map.getRuleId()); // 规则id
                    relEntity.setRulePropertyId(property.getRulePropertyId()); // 属性id
                    relEntity.setRulePropertyValue(property.getRulePropertyValue()); // 属性值
                    propertyRelService.save(relEntity);

                });
            }
            // 规则动作
            List<Long> actionRuleRelItem = reqVo.getActionRuleRelItem();
            if (!CollectionUtil.collectionIsNull(actionRuleRelItem)) {
                actionRuleRelItem.stream().forEach(actionId -> {
                    ActionRuleRelEntity actionRuleRelEntity = new ActionRuleRelEntity();
                    actionRuleRelEntity.setRuleId(map.getRuleId());
                    actionRuleRelEntity.setActionId(actionId);
                    // 保存动作规则关系表
                    boolean save = actionRuleRelService.save(actionRuleRelEntity);
                    if (save) {
                        // 更新动作参数属性值表中的 rule_action_rel_id(动作规则关系表的主键) 字段
                        actionParamValueInfoService.updateByActionParamId(actionId, actionRuleRelEntity.getRuleActionRelId());
                    }
                });
            }
        } catch (MappingException e) {
            throw new CustomException("保存规则信息失败");
        }
        return Result.ok();
    }

    /**
     * @return
     * @Author gz
     * @Description 详情信息
     * @Date 2019/7/16 9:43
     * @Param rulesId 规则id
     */
    public RulesInfoEntityReqVo getOne(Long rulesId) {
        return this.baseMapper.getOne(rulesId);
    }



}
